﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RegisteredServer.cs" company="">
//   
// </copyright>
// <summary>
//   Egy regisztrált szerver
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace DbDiff.Common.Model
{
    using System;
    using System.Xml;
    using Helper;

    /// <summary>
    /// Egy regisztrált szerver
    /// </summary>
    [Serializable]
    public class RegisteredServer : ICloneable
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="RegisteredServer"/> class.
        /// </summary>
        public RegisteredServer()
        {
            this.Name = string.Empty;
            this.AuthType = AuthType.Win;
            this.User = string.Empty;
            this.Password = string.Empty;
            this.Id = string.Empty;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="RegisteredServer"/> class.
        /// </summary>
        /// <param name="serverName">
        /// The server name.
        /// </param>
        public RegisteredServer(string serverName)
        {
            this.Name = serverName;
            this.AuthType = AuthType.Win;
            this.User = string.Empty;
            this.Password = string.Empty;
            this.Id = CreateRegisteredServerId(this.Name, this.AuthType, this.User, this.Password);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="RegisteredServer"/> class.
        /// </summary>
        /// <param name="serverName">
        /// The server name.
        /// </param>
        /// <param name="authType">
        /// The auth type.
        /// </param>
        /// <param name="user">
        /// The user name.
        /// </param>
        /// <param name="password">
        /// The password.
        /// </param>
        public RegisteredServer(string serverName, AuthType authType, string user, string password)
        {
            this.Id = CreateRegisteredServerId(serverName, authType, user, password);
            this.Name = serverName;
            this.AuthType = authType;
            this.User = user;
            this.Password = password;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="RegisteredServer"/> class.
        /// </summary>
        /// <param name="configNode">
        /// The config node.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// </exception>
        /// <exception cref="DbDiffException">
        /// </exception>
        public RegisteredServer(XmlNode configNode)
        {
            try
            {
                if (configNode == null)
                {
                    throw new ArgumentNullException("configNode");
                }

                this.Name = XmlHelper.GetAttributeValue(configNode, "name", true);
                string stringValue = XmlHelper.GetAttributeValue(configNode, "authtype",
                                                                 DiffClientDefaults.AUTHTYPEDEFAULT.ToString());
                this.AuthType = (AuthType)Enum.Parse(typeof(AuthType), stringValue);
                this.User = XmlHelper.GetAttributeValue(configNode, "user", string.Empty);
                this.Password = XmlHelper.GetAttributeValue(configNode, "password", string.Empty);
                this.Id = XmlHelper.GetAttributeValue(configNode, "id", CreateRegisteredServerId(this.Name, this.AuthType, this.User, this.Password));
            }
            catch (Exception e)
            {
                throw new DbDiffException("Invalid registeredserver configuration!", e);
            }
        }

        #endregion

        #region Fields & properties

        /// <summary>
        /// Gets the Server Id.
        /// </summary>
        public string Id { get; private set; }

        /// <summary>
        /// Gets Name.
        /// </summary>
        public string Name { get; private set; }

        /// <summary>
        /// Gets AuthType.
        /// </summary>
        public AuthType AuthType { get; private set; }

        /// <summary>
        /// Gets User.
        /// </summary>
        public string User { get; private set; }

        /// <summary>
        /// Gets Password.
        /// </summary>
        public string Password { get; private set; }

        #endregion

        #region public function

        /// <summary>
        /// The create registered server id.
        /// </summary>
        /// <param name="server">
        /// The server.
        /// </param>
        /// <param name="authType">
        /// The auth type.
        /// </param>
        /// <param name="user">
        /// The user name.
        /// </param>
        /// <param name="password">
        /// The password.
        /// </param>
        /// <returns>
        /// The registered server id.
        /// </returns>
        public static string CreateRegisteredServerId(string server, AuthType authType, string user, string password)
        {
            string serverID = string.Empty;

            switch (authType)
            {
                case AuthType.Sql:
                    serverID = string.Format("{0} : {1} : {2}", server, authType, user);
                    break;
                case AuthType.Win:
                    serverID = string.Format("{0} : {1}", server, authType);
                    break;
                case AuthType.Azure:
                    serverID = string.Format("tcp:{0}.database.windows.net", server);
                    break;
            }

            return serverID;
        }

        #region ICloneable Members

        /// <summary>
        /// Clone the server object.
        /// </summary>
        /// <returns>
        /// The cloned server.
        /// </returns>
        public object Clone()
        {
            return new RegisteredServer(this.Name, this.AuthType, this.User, this.Password);
        }

        #endregion

        /// <summary>
        /// The save method.
        /// </summary>
        /// <param name="writer">
        /// The xml writer.
        /// </param>
        public void Save(XmlWriter writer)
        {
            writer.WriteStartElement("Server");
            writer.WriteAttributeString("Id", this.Id);
            writer.WriteAttributeString("Name", this.Name);
            writer.WriteAttributeString("AuthType", this.AuthType.ToString());
            writer.WriteAttributeString("User", this.User);
            writer.WriteAttributeString("Password", this.Password);
            writer.WriteEndElement();
        }

        /// <summary>
        /// The load.
        /// </summary>
        /// <param name="serverNode">
        /// The server node.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// </exception>
        /// <exception cref="ApplicationException">
        /// </exception>
        public void Load(XmlNode serverNode)
        {
            if (serverNode == null)
            {
                throw new ArgumentNullException("serverNode");
            }

            this.Id = XmlHelper.GetAttributeValue(serverNode, "Id");
            this.Name = XmlHelper.GetAttributeValue(serverNode, "Name");

            try
            {
                string stringValue = XmlHelper.GetAttributeValue(serverNode, "AuthType");
                this.AuthType = (AuthType)Enum.Parse(typeof(AuthType), stringValue, true);
            }
            catch
            {
                throw new ApplicationException("Invalid or empty RegisteredServer.AuthType");
            }

            this.User = XmlHelper.GetAttributeValue(serverNode, "User");
            this.Password = XmlHelper.GetAttributeValue(serverNode, "Password");
        }

        /// <summary>
        /// Override the tostring
        /// </summary>
        /// <returns>
        /// The server if
        /// </returns>
        public override string ToString()
        {
            return this.Id;
        }

        #endregion
    }        
}